/**
 * All Rights Reserved , Copyright (C) 2020 , 青岛鼎信通讯股份有限公司
 * <p>
 * BaseOperateRecordService
 * 操作记录
 * <p>
 * 修改纪录
 * 2020-12-01 版本：1.0 zhanglongfei 创建。
 *
 * @version 版本：1.0
 * @author 作者：zhanglongfei
 * 创建日期：2020-12-01
 */
package com.topscomm.base.service.impl;

import com.alibaba.druid.sql.ast.expr.SQLCaseExpr.Item;
import com.topscomm.base.BaseSystemConst;
import com.topscomm.base.pojo.BaseOperateRecordEntity;
import com.topscomm.base.service.IBaseOperateRecordService;
import com.topscomm.base.service.impl.auto.BaseOperateRecordServiceAuto;
import com.topscomm.basic.BasicEntity;
import com.topscomm.basic.exception.ServiceException;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import com.topscomm.tap.common.DatacodeCache;
import com.topscomm.tap.common.SessionUserBean;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

@Service(value = "baseOperateRecordService")
@Scope(value = "singleton")
public class BaseOperateRecordService extends BaseOperateRecordServiceAuto implements IBaseOperateRecordService {

    /**
     * @Description: 根据sourcetype, sourceid, operatetype增加操作记录
     * @Author: mengmeng
     * @Date: 2021/7/21 15:27
     * @Version: 1.0
     */
    @Override
    @Transactional
    public void insertOperateRecord(String sourceType, List<String> sourceIdList, String operateType, String userCode, String userName, String deptCode, String orgCode) {
        // 校验必填参数
        validateParam(sourceType, sourceIdList, operateType, userCode);
        // 查重，是否存在相应的操作记录
        sourceIdList = sourceIdList.stream().distinct().collect(Collectors.toList());
        Map<String, Object> param = new HashMap<>();
        param.put("sourceType", sourceType);
        param.put("sourceIdList", sourceIdList);
        param.put("operateType", operateType);
        param.put("userCode", userCode);
        List<BaseOperateRecordEntity> oldRecord = this.query(param, "selectEntityByParam");
        // 假定存在操作记录
        boolean exitOperateRecord = 0 != oldRecord.size();
        Date now = new Date();
        if (exitOperateRecord) {
            // 存在相同的操作记录不需要增加新的操作记录, 修改操作时间
            param.put("operateDate", now);
            this.update(param, "updateOperateDate");
        }

        Set<String> oldRecordIdSet = oldRecord.stream().map(BaseOperateRecordEntity::getSourceid).collect(Collectors.toSet());
        // 不存在操作记录需要插入操作记录
        sourceIdList = sourceIdList.stream().filter(item -> !oldRecordIdSet.contains(item)).collect(Collectors.toList());
        if (sourceIdList.size() == 0) {
			return;
		}
        List<BasicEntity> baseOperateRecordList = new ArrayList<>();
        BaseOperateRecordEntity baseOperateRecord;
        for (String sourceId : sourceIdList) {
            baseOperateRecord = new BaseOperateRecordEntity();
            baseOperateRecord.setUsercode(userCode);
            baseOperateRecord.setUsername(userName);
            baseOperateRecord.setDeptcode(deptCode);
            baseOperateRecord.setOrgcode(orgCode);
            baseOperateRecord.setSourcetype(sourceType);
            baseOperateRecord.setSourceid(sourceId);
            baseOperateRecord.setOperatedate(now);
            baseOperateRecord.setOperatetype(operateType);
            baseOperateRecordList.add(baseOperateRecord);
        }
        this.insertBatch(baseOperateRecordList);
    }

    /**
     * @Description: 校验必填参数
     * @Author: mengmeng
     * @Date: 2021/7/21 15:36
     * @Version: 1.0
     */
    private void validateParam(String sourceType, List<String> sourceIdList, String operateType, String userCode) {
        if (StringUtil.isEmpty(sourceType)) {
            throw new ServiceException("sourceType 不能为空");
        }
        if (CollectionUtils.isEmpty(sourceIdList)) {
            throw new ServiceException("sourceIdList 不能为空");
        }
        if (StringUtil.isEmpty(operateType)) {
            throw new ServiceException("operateType 不能为空");
        }
        if (StringUtil.isEmpty(userCode)) {
            throw new ServiceException("userCode 不能为空");
        }
    }

    @Override
    public void setDispFields(Map<String, Object> mapRow, DatacodeCache datacodeCache) {
        super.setDispFields(mapRow, datacodeCache);
        String temp;
        if (mapRow.get("sourcetype") != null) {
            temp = mapRow.get("sourcetype").toString();
            mapRow.put("dispsourcetype", datacodeCache.getValueDynamic("MarkSourceType", temp, "code", "name"));
            // 单据状态
            if (mapRow.get("state") != null) {
                String state = mapRow.get("state").toString();
                if (BaseSystemConst.ItrMarkSourceType.ItrTechnicalService.equals(temp)) {
                    mapRow.put("dispstate", datacodeCache.getValueDynamic("ItrTechServiceState", state, "code", "name"));
                } else if (BaseSystemConst.ItrMarkSourceType.ItrTask.equals(temp)) {
                    mapRow.put("dispstate", datacodeCache.getValueDynamic("ItrTaskState", state, "code", "name"));
                } else if (BaseSystemConst.ItrMarkSourceType.ItrUntechnicalService.equals(temp)
                        || BaseSystemConst.ItrMarkSourceType.ItrProblemUpgrade.equals(temp)) {
                    mapRow.put("dispstate", datacodeCache.getValueDynamic("TapApprovalBillState", state, "code", "name"));
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeOperateMarkState(Map<String, Object> operateMap, SessionUserBean sessionUserBean) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendLineSingle("sourcetype='{0}' and sourceid='{1}'",
                ConvertUtil.convertToString(operateMap.get("sourcetype")),
                ConvertUtil.convertToString(operateMap.get("sourceid")));
        sql.appendLineSingle("and operatetype='{0}' and usercode='{1}'", BaseSystemConst.BaseOperateTypeEnum.Mark,
                sessionUserBean.getUser().getCode());
        // 不论是关注还是取消关注，均进行数据的删除操作
        this.deleteByWhere(sql.toString());
        String type = ConvertUtil.convertToString(operateMap.get("type"));
        // 如果是关注操作，在进行数据的插入
        if ("1".equals(type)) {
            operateMap.put(BaseOperateRecordEntity.FieldUsercode, sessionUserBean.getUser().getCode());
            operateMap.put(BaseOperateRecordEntity.FieldUsername, sessionUserBean.getUser().getName());
            operateMap.put(BaseOperateRecordEntity.FieldOrgcode, sessionUserBean.getOrg().getCode());
            operateMap.put(BaseOperateRecordEntity.FieldDeptcode, sessionUserBean.getDept().getCode());
            operateMap.put(BaseOperateRecordEntity.FieldOperatedate, new Date());
            BasicEntity operateRecordEntity = new BaseOperateRecordEntity();
            operateRecordEntity = operateRecordEntity.convertFromMap(operateMap);
            this.insert(operateRecordEntity);
        }
    }

    public List<Map<String, Object>> getMarkedData(List<Map<String, Object>> tempList, String tableName,String usercode) {
        StringBuffer sBuffer = new StringBuffer();
        tempList.forEach(m -> {
            sBuffer.append("'").append(ConvertUtil.convertToString(m.get("id"))).append("'").append(",");
        });
        String sourceids = sBuffer.substring(0, sBuffer.length() - 1);
        StringBufferProxy readMarkSql = new StringBufferProxy();
        readMarkSql.appendSingle(
                " sourcetype = '{0}' and usercode = '{1}' and sourceid in ({2}) and operatetype = '{3}'", tableName,
                usercode, sourceids, BaseSystemConst.BaseOperateTypeEnum.Mark);
        List<BaseOperateRecordEntity> operateRecordEntities = this.queryByWhere(readMarkSql.toString());
        for (Map<String, Object> temp : tempList) {
            String id = ConvertUtil.convertToString(temp.get("id"));
            Optional<BaseOperateRecordEntity> find = operateRecordEntities.stream()
                    .filter(m -> m.getSourceid().equals(id)).findAny();
            if (!find.isPresent()) {
                temp.put("markflag", "0");
            } else {
                temp.put("markflag", "1");
            }
        }
        return tempList;
    }

    @Override
    public String queryMarkedInfo(String sourcetype, String sourceid,String taskids) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" sourcetype = '{0}' and sourceid = {1} and operatetype = '{2}' ",sourcetype,sourceid,BaseSystemConst.BaseOperateTypeEnum.Mark);
        List<BaseOperateRecordEntity> entities = this.queryByWhere(sql.toString());
        // 项目下不存在任务，taskid为空，不执行sql语句防止报错
        if (!StringUtil.isEmpty(taskids)) {
            sql.clear();
            sql.appendSingle(" sourcetype = '{0}' and sourceid in ({1}) and operatetype = '{2}' ","MpmProjectTask",taskids,BaseSystemConst.BaseOperateTypeEnum.Mark);
            List<BaseOperateRecordEntity> entities2 = this.queryByWhere(sql.toString());
            entities.addAll(entities2);
        }
        String markedinfo = entities.stream().map(item->item.getUsername()+"["+item.getUsercode()+"]").distinct().collect(Collectors.joining(","));
        return markedinfo;
    }

    public String queryMarkedInfoByTask(String sourcetype, String sourceid,String projectcode) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" sourcetype = '{0}' and sourceid = {1} and operatetype = '{2}'",sourcetype,sourceid,BaseSystemConst.BaseOperateTypeEnum.Mark);
        List<BaseOperateRecordEntity> entities = this.queryByWhere(sql.toString());
        sql.clear();
        sql.appendSingle(" sourcetype = '{0}' and sourceid in (select id from MpmProject where projectcode = '{1}') and operatetype = '{2}'","MpmProject",projectcode,BaseSystemConst.BaseOperateTypeEnum.Mark);
        List<BaseOperateRecordEntity> entities2 = this.queryByWhere(sql.toString());
        entities.addAll(entities2);
        String markedinfo = entities.stream().map(item->item.getUsercode()).distinct().collect(Collectors.joining("','","'","'"));
        return markedinfo;
    }

    /**
     * @Description: 获取标记信息
     * @Author: houyuhang
     * @Date: 2023/01/10
     */
    @Override
    public List<Map<String, Object>> querySignInfo(Map<String, Object> paraMap) {
        StringBufferProxy sql = new StringBufferProxy();
        sql.appendSingle(" enabled = 1 and sourceid in ({0}) and sourcetype = '{1}' and operatetype = '{2}' and (usercode = '{3}' or ',' || operatedescription || ',' like '%,{3},%') ",
                ConvertUtil.convertToString(paraMap.get("sourceid")), ConvertUtil.convertToString(paraMap.get("sourcetype")), ConvertUtil.convertToString(paraMap.get("operatetype")), ConvertUtil.convertToString(paraMap.get("usercode")));
        if (paraMap.containsKey("sidx") && paraMap.containsKey("sord")) {
            sql.appendSingle(" order by {0} {1}, id desc ", ConvertUtil.convertToString(paraMap.get("sidx")), ConvertUtil.convertToString(paraMap.get("sord")));
        }
        return this.queryMapByWhere(sql.toString());
    }
    /**
     * @Description: 新增mpm标记信息
     * @Author: houyuhang
     * @Date: 2023/01/10
     */
    @Override
    public Map<String, Object> insertSign(Map<String, Object> paraMap) {
        BaseOperateRecordEntity entity = new BaseOperateRecordEntity();
        entity.convertFromMap(paraMap);
        this.insert(entity);
        return paraMap;
    }
}
